package com.yunyi.user.service.impl;

import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.yunyi.exception.ExceptionCast;
import com.yunyi.model.mappers.company.SysPostMapper;
import com.yunyi.model.mappers.media.FileMediaMapper;
import com.yunyi.model.mappers.work.WorkTimeMapper;
import com.yunyi.model.mappers.worker.WorkerInfoMapper;
import com.yunyi.model.work.WorkerTime;
import com.yunyi.model.worker.dto.WorkOrderInfo;
import com.yunyi.model.worker.dto.WorkTimeDto;
import com.yunyi.response.CommonCode;
import com.yunyi.user.constant.Constant;
import com.yunyi.user.redisSevice.RedisService;
import com.yunyi.user.response.UserCode;
import com.yunyi.user.service.WorkerService;
import com.yunyi.util.DateUtil;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * @ClassName UserServiceImpl
 * @Description 用户接口操作service
 * @Author leizhang
 * Date 2021/8/16 4:31 下午
 * @Version 1.0
 **/
@Service
public class WorkerServiceImpl implements WorkerService {
    @Autowired
    private WorkerInfoMapper workerInfoMapper;
    @Autowired
    private WorkTimeMapper workTimeMapper;
    @Autowired
    private FileMediaMapper fileMediaMapper;
    @Autowired
    private RedisService redisService;
    @Autowired
    private SysPostMapper sysPostMapper;

    /**
     * @param requestParam
     * @return com.yunyi.model.user.UserInfo
     * @Description : 用户信息获取
     * @Author : leizhang
     * @Date 4:47 下午 2021/8/16
     **/
    @Override
    public List<WorkTimeDto> getWorkerInfo(Map<String, Object> requestParam) throws Exception {
        if (requestParam == null || requestParam.isEmpty()) {
            throw new Exception("用户请求参数为空");
        }
        requestParam.put(Constant.WORK_TIME, DateUtils.addDays(new Date(), 1));
        requestParam.put(Constant.WORK_STATUS, Constant.NUMBER_1);
        List<WorkTimeDto> userInfo = workerInfoMapper.getWorkerInfo(requestParam);
        return userInfo;
    }

    /**
     * @param requestParam
     * @return void
     * <p>
     * {
     * companyId
     * sysPosts:[]
     * timeShiftType 班次类型
     * workType:"事件类型 1 员工信息初始化保存 2 员工信息修改",
     * ....workerInfo
     * }
     * @Description : 员工报名
     * @Author : leizhang
     * @Date 1:30 下午 2021/8/17
     **/
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int saveWorkInfo(Map<String, Object> requestParam) throws Exception {
        //参数校验
        int workType;
        if (null == requestParam || requestParam.isEmpty() || null == requestParam.get(Constant.WORK_TYPE)) {
            ExceptionCast.cast(CommonCode.INVALIDPARAM);
        }
        int status = 0;
        requestParam.putIfAbsent(Constant.STATUS, 1);
        List<WorkTimeDto> workerInfo = this.getWorkerInfo(requestParam);
        Date afterDay = DateUtils.addDays(new Date(), 1);
        requestParam.put(Constant.WORK_TIME, afterDay);
        //DateUtils.addDays(new Date(),(int)requestParam.get(Constant.THRESHOLD) )
        requestParam.put(Constant.END_TIME,DateUtils.addDays(new Date(),(int)requestParam.get(Constant.THRESHOLD) ));
        //获取当前班次的剩余名额
        //修改redis中的候选人员数量和班次人员数量
        Integer workerId = null;
        String orderCode = DateUtil.getDayTimeAfter();
        requestParam.putIfAbsent(Constant.ORDER_CODE, orderCode);
        if ((workType = (int) requestParam.get(Constant.WORK_TYPE)) == 1) {
            //员工信息初始化
            if (null != workerInfo && workerInfo.size() > 0) {
                ExceptionCast.cast(CommonCode.FAIL);
            }
            status = this.saveRedisInfo(requestParam);

            requestParam.put(Constant.WORK_STATUS, status);
            //保存员工休息
            workerInfoMapper.saveWorkerInfo(requestParam);
            workerId = (Integer) requestParam.get(Constant.ID);
            if (null == workerId || workerId < 0) {
                ExceptionCast.cast(CommonCode.FAIL);
            }
            requestParam.put(Constant.WORKER_ID, workerId);
            //保存员工班次数据
            workTimeMapper.saveWorkTimeInfo(requestParam);
        } else if (workType == 2) {
            //员工信息修改
            if (null == workerInfo && workerInfo.size() < 0) {
                ExceptionCast.cast(CommonCode.FAIL);
            }
            workerInfoMapper.updateWorkerInfo(requestParam);
            requestParam.put(Constant.WORKER_ID, workerId = (Integer) requestParam.get(Constant.ID));
            requestParam.put("cancellStatus", 3);
            WorkerTime workerTimeInfo = workTimeMapper.getWorkerTimeInfo(requestParam);
            //当天没有报名 或者 当天取消了
            if (null == workerTimeInfo || workerTimeInfo.getStatus() > 3) {
                //当前员工没有报名
                status = saveRedisInfo(requestParam);
                requestParam.put(Constant.WORK_STATUS, status);
                workTimeMapper.saveWorkTimeInfo(requestParam);
            } else {
                //已报名修改报名信息workerTimeInfo
                int timeShiftType = workerTimeInfo.getTimeShiftType();
                if (timeShiftType != (int) requestParam.get(Constant.TIME_SHIFT_TYPE)) {
                    Map<String, Object> resultMap = redisService.updateWorkerNumber2(requestParam.get(Constant.TIME_SHIFT_TYPE).toString(), requestParam.get(Constant.APP_ID).toString(), String.valueOf(timeShiftType));
                    status = (int) resultMap.get(Constant.STATUS);
                    if (null != resultMap.get(Constant.APP_ID)) {
                        Map<String, Object> requestMap = Maps.newHashMap();
                        requestMap.put(Constant.WORK_STATUS, Constant.NUMBER_1);
                        requestMap.put(Constant.WORK_TIME, DateUtils.addDays(new Date(), 1));
                        requestMap.put(Constant.APP_ID, resultMap.get(Constant.APP_ID));
                        requestMap.put(Constant.UPDATE_STATUS, Constant.NUMBER_3);
                        workTimeMapper.updateWorkerTimeInfoByAppId(requestMap);
                    }
                    if (Constant.NUMBER_0 != status) {
                        requestParam.put(Constant.WORK_STATUS, resultMap.get(Constant.STATUS));
                        requestParam.put("updateId", workerTimeInfo.getId());
                        workTimeMapper.updateWorkerTime(requestParam);
                    }
                }
            }
        }
        List<Map<String, Object>> imgList = Lists.newLinkedList();
        //保存图片与用户的关联关系
        Map<String, Object> imgMap = null;
        if (null != requestParam.get(Constant.ID_CARD_IMG_ID) && StringUtils.isNotBlank(requestParam.get(Constant.ID_CARD_IMG_ID).toString())) {
            //身份证
            imgMap = Maps.newHashMap();
            imgMap.put(Constant.WORKER_ID, workerId);
            imgMap.put(Constant.MEDIA_FILE_ID, requestParam.get(Constant.ID_CARD_IMG_ID));
            imgMap.put(Constant.APP_ID, requestParam.get(Constant.APP_ID));
            imgMap.put(Constant.TAG, 1);
            imgList.add(imgMap);
        }
        if (null != requestParam.get(Constant.BANK_CARD_IMG_ID) && StringUtils.isNotBlank(requestParam.get(Constant.BANK_CARD_IMG_ID).toString())) {
            //银行卡
            imgMap = Maps.newHashMap();
            imgMap.put(Constant.WORKER_ID, workerId);
            imgMap.put(Constant.MEDIA_FILE_ID, requestParam.get(Constant.BANK_CARD_IMG_ID));
            imgMap.put(Constant.APP_ID, requestParam.get(Constant.APP_ID));
            imgMap.put(Constant.TAG, 2);
            imgList.add(imgMap);
        }
        fileMediaMapper.saveFileMediaWorker(imgList);
        //保存员工熟悉的工作岗位
        this.saveWorkerPosts(requestParam);
        return status;
    }

    private void saveWorkerPosts(Map<String, Object> requestMap) {
        if (null != requestMap.get(Constant.SYS_POSTS)) {
            sysPostMapper.delWorkerPosts(requestMap);
            List<Map<String, Object>> postsMap = Lists.newArrayList();
            if (requestMap.get(Constant.SYS_POSTS) instanceof List) {
                Map<String, Object> map = null;
                List<Integer> postsId = (List) requestMap.get(Constant.SYS_POSTS);
                for (Integer integer : postsId) {
                    map = Maps.newHashMap();
                    map.put(Constant.WORKER_ID, requestMap.get(Constant.WORKER_ID));
                    map.put(Constant.APP_ID, requestMap.get(Constant.APP_ID));
                    map.put(Constant.POST_ID, integer);
                    postsMap.add(map);
                }
            }
            sysPostMapper.saveWorkerPosts(postsMap);
        }
    }

    private int saveRedisInfo(Map<String, Object> requestMap) throws Exception {
        int status = redisService.updateWorkerNumber(requestMap.get(Constant.TIME_SHIFT_TYPE).toString(), requestMap.get(Constant.APP_ID).toString());
        if (status == Constant.NUMBER_0) {
            throw new Exception("redis 更新员工信息错误");
        }
        return status;
    }

    /**
     * @param requestParam
     * @return void
     * <p>
     * { status : 2-上班签到 6-下班签到(完成),
     * orderCode:
     * worker_id:
     * app_id:
     * }
     * @Description : 员工上班签到
     * @Author : leizhang
     * @Date 7:00 下午 2021/8/17
     **/
    @Override
    public void updateWorkTime(Map<String, Object> requestParam) throws Exception {
        if (null == requestParam || requestParam.isEmpty() || null == requestParam.get(Constant.WORKER_ID)
                || null == requestParam.get(Constant.APP_ID) || null == requestParam.get(Constant.STATUS)) {
            ExceptionCast.cast(CommonCode.INVALIDPARAM);
        }
        //1,签到修改数据库状态
        requestParam.put(Constant.ORDER_CODE_STR, requestParam.get(Constant.ORDER_CODE));
        int status = (int) requestParam.get(Constant.STATUS);

        requestParam.put("statusWork", Constant.NUMBER_2 == status ? Constant.NUMBER_1 : Constant.NUMBER_6 == status ? Constant.NUMBER_2 : 0);
        if (Constant.NUMBER_2 == status) {
            requestParam.put(Constant.WORK_TIME, DateUtils.addDays(new Date(), 0));
        } else if (Constant.NUMBER_6 == status) {
            requestParam.remove(Constant.WORK_TIME);
            requestParam.put(Constant.OFF_WORK_TIME, DateUtils.addDays(new Date(), (int) requestParam.get(Constant.THRESHOLD) - 1));
        }

        WorkerTime workerTimeInfo = workTimeMapper.getWorkerTimeInfo(requestParam);
        if (null == workerTimeInfo) {
            ExceptionCast.cast(UserCode.No_APPOINTMENT);
        }
        requestParam.put(status == Constant.NUMBER_2 ? Constant.SIGN_IN_TIME : status == Constant.NUMBER_6 ? Constant.OFF_WORK_TIME : null, new Date());
        requestParam.putIfAbsent(Constant.WORK_STATUS, status);
        workTimeMapper.updateWorkerTimeInfo(requestParam);
        if (Constant.NUMBER_6 == status) {
            //2.签到计算当前人员的参工次数
             redisService.setWorkerTime(requestParam);
        }

    }

    /**
     * @param requestParam
     * @return void
     * <p>
     * {workStatus: 工作状态 4-取消候选 5-取消报名
     * workerId:员工id
     * timeShiftId:班次表id
     * appId:
     * }
     * @Description : 更新工作状态
     * @Author : leizhang
     * @Date 10:27 下午 2021/8/21
     **/
    @Override
    public void updateWorkStatus(Map<String, Object> requestParam) throws Exception {

        if (null == requestParam || requestParam.isEmpty() ||
                null == requestParam.get(Constant.WORK_STATUS)
                || null == requestParam.get(Constant.APP_ID)
        ) {
            ExceptionCast.cast(CommonCode.INVALIDPARAM);
        }
        int status = (int) requestParam.get(Constant.WORK_STATUS);
        //1.更新工作状态表
        Date date = DateUtils.addDays(new Date(), 1);
        requestParam.put(Constant.WORK_TIME, date);
        requestParam.put(Constant.CANCELLATION_TIME, new Date());
        requestParam.put(Constant.ORDER_CODE_STR,requestParam.get(Constant.ORDER_CODE));
        workTimeMapper.updateWorkerTimeInfo(requestParam);
        if (Constant.NUMBER_4 == status) {
            //status == 4 取消候选 去除redis中的候选记录
            redisService.leaveQueue(requestParam.get(Constant.TIME_SHIFT_TYPE).toString(), requestParam.get(Constant.APP_ID).toString());
        } else if (Constant.NUMBER_5 == status) {
            Object result = redisService.descWorkerNumber(requestParam.get(Constant.TIME_SHIFT_TYPE).toString(), requestParam.get(Constant.APP_ID).toString());
            if (null != result) {
                if (!result.toString().equals(requestParam.get(Constant.APP_ID))) {
                    //返回appId 更新数据当前工作状态为后补装报名状态
                    Map<String, Object> requestMap = Maps.newHashMap();
                    requestMap.put(Constant.WORK_STATUS, Constant.NUMBER_1);
                    requestMap.put(Constant.WORK_TIME, date);
                    requestMap.put(Constant.APP_ID, result);
                    requestMap.put(Constant.UPDATE_STATUS, Constant.NUMBER_3);
                    workTimeMapper.updateWorkerTimeInfoByAppId(requestMap);
                }
            }
        }
    }

    /**
     * @param requestParam
     * @return java.util.List<com.yunyi.model.worker.dto.WorkOrderInfo>
     * <p>
     * {
     * workStatus: 工作状态 1-待签到 2-已签到 3-候选 6-完成
     * }
     * @Description : 员工订单信息
     * @Author : leizhang
     * @Date 12:50 上午 2021/8/22
     **/
    @Override
    public List<WorkOrderInfo> getWorkInfoByStatus(Map<String, Object> requestParam) throws Exception {
        if (null == requestParam || requestParam.isEmpty() ||
                null == requestParam.get(Constant.WORK_STATUS) ||
                null == requestParam.get(Constant.APP_ID)
        ) {
            ExceptionCast.cast(CommonCode.INVALIDPARAM);
        }
        int workStatus = Integer.valueOf(requestParam.get(Constant.WORK_STATUS).toString());
        Date afterDay = null;
        Date timeTorr = null;
        switch (workStatus) {
            case Constant.NUMBER_1:
                afterDay = DateUtils.addDays(new Date(), 1);
                break;
            case Constant.NUMBER_2:
                afterDay = DateUtils.addDays(new Date(), 0);
                timeTorr = DateUtils.addDays(new Date(), -1);
                //requestParam.put(Constant.END_TIME_TORR, afterDay);
                requestParam.put(Constant.END_TIME_TORR, timeTorr);
                break;
            case Constant.NUMBER_3:
                afterDay = DateUtils.addDays(new Date(), 1);
                break;
            default:
                afterDay = null;
        }
        requestParam.put(Constant.WORK_TIME, afterDay);
        List<WorkOrderInfo> workOrderInfos = null;
        if (Constant.NUMBER_2==workStatus) {
            workOrderInfos = workerInfoMapper.getWorkerInfoByStatusOf2(requestParam);
        }else {
            workOrderInfos = workerInfoMapper.getWorkerInfoByStatus(requestParam);
        }
        if (Constant.NUMBER_3 == workStatus && !workOrderInfos.isEmpty()) {
            for (WorkOrderInfo workOrderInfo : workOrderInfos) {
                //获取排队人数
                int queueNumber = redisService.positionBeforeNum(String.valueOf(workOrderInfo.getWorkType()), workOrderInfo.getAppId());
                workOrderInfo.setQueueNumber(queueNumber);
            }
        }
        return workOrderInfos;
    }
}
